Eidhoven, 1995:

   IOI. 19 (???) Intr-un magazin, fiecare tip de produse are un pret. De exemplu, 
pretul unei flori este de 2 ICU (Informatics Currency Units) iar pretul unui vas 
este de 5 ICU. Pentru a atrage ct mai multi cumparatori, magazinul introduce 
anumite oferte speciale.
   O oferta speciala consta din unul sau mai multe produse oferite la un pret 
mai mic. Exemple: trei flori se dau pentru 5 ICU n loc de 6, sau doua vase 
mpreuna cu o floare costa 10 ICU n loc de 12.
   Sa se scrie un program care calculeaza pretul pe care l da un cumparator 
pentru o anumita solicitare. Costul trebuie sa fie ct mai mic posibil, n 
functie de ofertele speciale. Nu se poate adauga nimic, chiar daca aceasta ar 
duce la scaderea pretului.
   Pentru preturile si ofertele din exemplul de mai sus, cel mai mic pret platit 
pentru 3 flori si 2 vase este de 14 ICU: doua vase si o floare costa (redus) 
10 ICU, iar 2 flori costa pretul (normal) de 4 ICU.
Intrare:
   Datele de intrare apar n doua fisiere: INPUT.TXT si OFFER.TXT. Primul fisier 
descrie produsele (din "cosul de cumparaturi"). Al doilea fisier descrie ofertele 
speciale. Ambele fisiere contin numai numere ntregi.
Prima linie din INPUT.TXT da numarul b de produse diferite din cosul de 
cumparaturi (0b5). Fiecare din cele b linii care urmeaza contine trei valori: 
c,k,p. Valoarea c este codul (unic) al unui produs (1c999). Valoarea k indica 
cte bucati din acest produs sunt n cos (1k5). Valoarea p este pretul normal 
pentru fiecare bucata (1p999). De retinut ca n cos nu pot ncape mai mult de
5*5=25 bucati.
 Prima linie din OFFER.TXT contine numarul s de oferte speciale (0s99). Fiecare 
din urmatoarele s linii contine o oferta speciala data prin structura sa si prin 
pretul redus oferit. Primul numar n de pe fiecare linie este numarul de produse 
diferite care fac parte din oferta (1n5). Urmatoarele n perechi de numere (c,k) 
indica situatia n care k bucati (1k5) din produsul de cod c(1c999) sunt n 
aceasta oferta. Ultimul numar p de pe linie arata pretul redus (1p999); acest
pret per oferta este mai mic dect suma preturilor normale.
Iesire: 
   Se scrie n fisierul OUTPUT.TXT o linie pe care se afla cel mai mic pret 
posibil care trebuie platit pentru produsele din fisierul de intrare.
Exemplu: Daca:
INPUT.TXT
2
7 3 2
8 2 5
OFFER.TXT
2
1 7 3 5
2 7 1 8 2 10
atunci iesirea va fi
OUTPUT.TXT
14
===================================
Solutia 1 (Bogdan batog - Buucresti)
type
    ofert=record
             a:array[1..5] of byte;
             p:integer;
          end;
    matr =array[0..5,0..5,0..5,0..5,0..5] of integer;
var
   fil                          :text;
   n,b,f,i,j,s,c1,c2,h          :integer;
   c,k,p                        :array[1..5] of integer;
   o                            :array[1..100] of ofert;
   cost                         :matr;

Procedure solv;
var i1,i2,i3,i4,i5:integer;
begin
     for i1:=0 to 5 do
      for i2:=0 to 5 do
       for i3:=0 to 5 do
        for i4:=0 to 5 do
         for i5:=0 to 5 do
         cost[i1,i2,i3,i4,i5]:=p[1]*i1+p[2]*i2+p[3]*i3+p[4]*i4+p[5]*i5;

     for i1:=0 to k[1] do
      for i2:=0 to k[2] do
       for i3:=0 to k[3] do
        for i4:=0 to k[4] do
         for i5:=0 to k[5] do
         for f:=1 to s do
         if (i1-o[f].a[1]>=0) and (i2-o[f].a[2]>=0) and (i3-o[f].a[3]>=0) and
            (i4-o[f].a[4]>=0) and (i5-o[f].a[5]>=0) then
         begin
              if cost[i1-o[f].a[1],i2-o[f].a[2],i3-o[f].a[3],
                 i4-o[f].a[4],i5-o[f].a[5]]+o[f].p<cost[i1,i2,i3,i4,i5] then
                cost[i1,i2,i3,i4,i5]:=cost[i1-o[f].a[1],i2-o[f].a[2],i3-o[f].a[3],
                 i4-o[f].a[4],i5-o[f].a[5]]+o[f].p;
         end;
     writeln(cost[k[1],k[2],k[3],k[4],k[5]])
end;

begin
     assign(fil,'input.txt'); reset(fil);
     readln(fil,b);
     for f:=1 to b do readln(fil,c[f],k[f],p[f]);
     close(fil);
     assign(fil,'offer.txt'); reset(fil);
     readln(fil,s);
     for f:=1 to s do
     begin
          read(fil,n);
          for i:=1 to n do
          begin
               read(fil,c1,c2);
               for j:=1 to 5 do if c[j]=c1 then h:=j;
               o[f].a[h]:=c2;
          end;
          readln(fil,o[f].p)
     end;
     close(fil);
     fillchar(cost,sizeof(cost),0);
     solv;
end.
------------------------------
Solutia 2 (Ovidiu Ghiorghioiu - Alba Iulia)
{Problema cu ofertele de la Inter.
Modificare: in loc de INPUT.TXT, OFFER.TXT si OUTPUT.TXT fisierele se numesc
respectiv ioi95a.in, ioi95a.dat, ioi95a.out.
}
type sir=array[1..5] of shortint;
     offer=record
                 nr:sir;
                 pr:integer;
                 nothing:byte;
     end;
var a:array[0..7775] of integer;
    _cod:array[1..999] of byte;
    o:array[1..100] of offer;
    what,p:sir;
    i,j,k,l,t,n,no,rno:integer;
    good:boolean;
    f:text;

procedure transform(var result:integer);
var i,r:integer;
begin
     r:=what[1];
     for i:=2 to n do r:=r*6+what[i];
     result:=r
end;

procedure citeste;
begin
     assign(f,'ioi95a.in');reset(f);
     read(f,n);
     for i:=1 to n do begin
         read(f,j,k,l);
         _cod[j]:=i;
         what[i]:=k;
         p[i]:=l;
     end;
     close(f);
     assign(f,'ioi95a.dat');reset(f);
     read(f,rno);
     for i:=1 to rno do begin
         read(f,t);
         good:=true;
         inc(no);
         for j:=1 to t do begin
             read(f,k,l);
             if _cod[k]=0 then begin
                good:=false;
                break
             end;
             o[no].nr[_cod[k]]:=l;
         end;
         if good then read(f,o[no].pr) else dec(no);
         readln(f);
     end;
     close(f);
end;

function value:integer;  {Calculeaza valoarea minima a lui what}
var min,code,i,val:integer;
begin
     transform(code);
     if a[code]=0 then begin
        min:=0;
        for i:=1 to n do inc(min,p[i]*what[i]);
        for i:=1 to no do if min>o[i].pr then begin
            for j:=1 to n do dec(what[j],o[i].nr[j]);
            good:=true;
            for j:=1 to n do if what[j]<0 then good:=false;
            if good then begin
               val:=o[i].pr+value;
               if min>val then min:=val;
            end;
            for j:=1 to n do inc(what[j],o[i].nr[j]);
        end;
        a[code]:=min;
     end;
     value:=a[code];
end;

procedure rezolva;
begin
     assign(f,'ioi95a.out');rewrite(f);
     writeln(f,value);
     close(f);
end;

begin
     citeste;
     rezolva;
end.
------------------------------
Solutia 3 (Mihai Stroe - Bucuresti)
var i1,i2,i3,i4,i5,i,j,k,l,m,n,cc,kk:longint;
    f1,f2,fo:text;
    a:array[0..5,0..5,0..5,0..5,0..5]of longint;
    c,nr,p:array[1..5]of longint;
    o:array[1..1000,1..5]of byte;
    pret:array[1..1000]of longint;

procedure readdata;
begin
  assign(f1,'input.txt');
  assign(f2,'offer.txt');
  assign(fo,'output.txt');
  reset(f1);
  reset(f2);
  rewrite(fo);
  readln(f1,n);
  for i:=1 to n do
      readln(f1,c[i],nr[i],p[i]);
  close(f1);
  readln(f2,k);
  for i:=1 to k do
      begin
        read(f2,m);
        for j:=1 to m do
            begin
              read(f2,cc,kk);
              l:=1;
              while cc<>c[l] do inc(l);
              o[i,l]:=kk;
            end;
        readln(f2,pret[i]);
      end;
  close(f2);
end;

procedure solve;
begin
  for i1:=0 to nr[1] do
      for i2:=0 to nr[2] do
          for i3:=0 to nr[3] do
              for i4:=0 to nr[4] do
                  for i5:=0 to nr[5] do
                      begin
                        a[i1,i2,i3,i4,i5]:=p[1]*i1+p[2]*i2+p[3]*i3+p[4]*i4+p[5]*i5;
                        for j:=1 to k do
                            if (o[j,1]<=i1)and(o[j,2]<=i2)and(o[j,3]<=i3)and(o[j,4]<=i4)and(o[j,5]<=i5)then
                               if pret[k]+a[i1-o[j,1],i2-o[j,2],i3-o[j,3],i4-o[j,4],i5-o[j,5]]<a[i1,i2,i3,i4,i5] then
                                  a[i1,i2,i3,i4,i5]:=pret[k]+a[i1-o[j,1],i2-o[j,2],i3-o[j,3],i4-o[j,4],i5-o[j,5]];
                      end;
  writeln(fo,a[i1,i2,i3,i4,i5]);
  close(fo);
end;

begin
  readdata;
  solve;
end.
------------------------------
